package org.grayrabbit.cms.plugin;
import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import org.grayrabbit.cms.entity.PluginVersion;
import org.grayrabbit.cms.extension.Startable;
import org.grayrabbit.cms.service.system.PluginVersionService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;


/**
 * @author sys53
 * @version 1.0
 * @created 06-一月-2012 15:45:13
 */
public class CmsPluginManager extends DefaultPluginManager implements Startable {
	private static Logger log = LoggerFactory.getLogger(CmsPluginManager.class);
	private  final PluginInstallationManager pluginInstallactionManager;
	private  PluginVersionService pluginVersionService;
	public CmsPluginManager( PluginInstallationManager installactionManager,PluginStateStore store,PluginLoaderFactory  pluginLoaderFactory,ModuleDescriptorFactory moduleDescriptorFactory){
		super(store,pluginLoaderFactory.getPluginLoaders(),moduleDescriptorFactory);
		this.pluginInstallactionManager = installactionManager;
//		pluginVersionService =(PluginVersionService) SpringUtil.getBean("pluginVersionServiceImpl");
	}

	public void start() throws PluginException{
		try {
			this.pluginInstallactionManager.processUpdates();
		} catch (PluginParseException e) {
		} catch (PluginException e) {
		}
		init();
		storePluginVersions();
	}

	private void storePluginVersions() {
		Map<String,PluginVersion> pluginVersionsByKey = getPluginVersionsByKey();
	    for (Plugin plugin :  getPlugins() )
	    {
	      storePluginVersion(plugin, (PluginVersion)pluginVersionsByKey.get(plugin.getKey()));
	      pluginVersionsByKey.remove(plugin.getKey());
	    }
	    deletePluginVersions(pluginVersionsByKey.values());
	}

	private void deletePluginVersions(Collection<PluginVersion> collection) {
		for(PluginVersion pv : collection){
			pluginVersionService.delete(pv);
		}
	}

	private void storePluginVersion(Plugin plugin,PluginVersion pluginVersion) {
		PluginVersion pv = new PluginVersion();
		String pluginKey = plugin.getKey();
	    PluginInformation pluginInformation = plugin.getPluginInformation();
	    String version = "unknown";
	    if (pluginInformation != null)
	    {
	      version = pluginInformation.getVersion();
	    }
	    pv.setVersion(version);
	    pv.setKey(pluginKey);
	    pv.setName(plugin.getName());
	    pv.setCreated(new Date());
	    pv.setIsAutoDeploy(Boolean.valueOf(plugin.isSystemPlugin()));
	    pv.setIsEnabled(Boolean.valueOf(plugin.isDefaultEnabled()));
	    for(PluginWebMenuItem item : plugin.getPluginWebMenuItems()){
	    	//-web-item,放置菜单的位置,type定义其类型：top_nav:顶部导航,catalog_nav:栏目导航,head_h_nav:会员中心头部横向导航,left_v_nav:会员中心左侧竖向导航, manage_config:后台管理配置
	    	if("catalog_nav".equalsIgnoreCase(item.getType())){
	    		pv.setCatalogNavUrl(item.getUrl());
	    	}else if("top_nav".equalsIgnoreCase(item.getType())){
	    		pv.setTopNavUrl(item.getUrl());
	    	}else if("head_h_nav".equalsIgnoreCase(item.getType())){
	    		pv.setHeadHNavUrl(item.getUrl());
	    	}else if("left_v_nav".equalsIgnoreCase(item.getType())){
	    		pv.setLeftVNavUrl(item.getUrl());
	    	}else if("manage_config".equalsIgnoreCase(item.getType())){
	    		pv.setManageConfigUrl(item.getUrl());
	    	}
	    }
	    if (pluginVersion == null)
	    {
	      log.info("Plugin with key '{}' and name '{}' and version '{}' is being added to the system.",new String[]{pluginKey,plugin.getName() ,version});
	    }
	    else if (!pluginVersion.getVersion().equals(version))
	    {
	    	
	      log.info("Plugin with key '{}' and name '{}' and version '{}' is being updated to version '{}'.",new String[]{pluginKey,plugin.getName() ,pluginVersion.getVersion(),version});
	    }else{
	    	pv.setVersionId(pluginVersion.getVersionId());
	    }
	    pluginVersionService.save(pv);
	}

	private Map<String, PluginVersion> getPluginVersionsByKey() {
		 Map<String, PluginVersion> versionsByKey = new HashMap<String, PluginVersion>();
//		    List<PluginVersion> pluginVersions = this.pluginVersionService.getAll();
//		    for (PluginVersion pluginVersion :  pluginVersions)
//		    {
//		      versionsByKey.put(pluginVersion.getKey(), pluginVersion);
//		    }
		    return versionsByKey;
	}

}